#ifndef __MANAGER_CRC_H__
#define __MANAGER_CRC_H__

#define CRC8_POLYNOMIAL 0x5E        /**< x^8 + x^6 + x^4 + x^3 + x^2 + 1 */
#define CRC16_POLYNOMIAL 0x8005     /**< x^16 + x^15 + x^2 + 1 */
#define CRC32_POLYNOMIAL 0x04C11DB7 /**< x^32 + x^28 + x^27 + x^26 + x^25 + x^23 + x^22 + x^20 + x^19 + x^18 + x^14 + x^13 + x^11 + x^10 + x^9 + x^8 + x^6 + 1 */

/**
 * CRC init value
 */
#define CRC8_INIT_VALUE 0xF5
#define CRC16_INIT_VALUE 0xF5F5
#define CRC32_INIT_VALUE 0xF5F5F5F5

#define CRC8_LEN (1)
#define CRC16_LEN (2)
#define CRC32_LEN (4)

void crc32_init_lut(const unsigned int poly, unsigned int *lut);

unsigned int crc32_calc_lut(const unsigned char *data,
                            unsigned short data_len,
                            unsigned int crc,
                            const unsigned int *lut);

unsigned char crc8_calc(const unsigned char *data, unsigned int data_len);
unsigned short crc16_calc(const unsigned char *data, unsigned int data_len);
unsigned int crc32_calc(const unsigned char *data, unsigned int data_len);

void crc8_init(void);
void crc16_init(void);
void crc32_init(void);

#endif /* __MANAGER_CRC_H__ */
